package com.zbl.zblproject.erp.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Strings;
import com.zbl.zblproject.core.entity.AdminUser;
import com.zbl.zblproject.core.entity.RechargeLog;
import com.zbl.zblproject.core.entity.Result;
import com.zbl.zblproject.core.entity.Supplier;
import com.zbl.zblproject.core.mapper.AdminUserMapper;
import com.zbl.zblproject.core.mapper.OrderMapper;
import com.zbl.zblproject.core.mapper.RechargeLogMapper;
import com.zbl.zblproject.core.mapper.SupplierMapper;
import com.zbl.zblproject.core.utils.ResultUtil;
import com.zbl.zblproject.core.utils.StringUtil;
import com.zbl.zblproject.core.utils.TimeUtil;
import com.zbl.zblproject.erp.entity.ErpFinanceLog;
import com.zbl.zblproject.erp.entity.ErpOrder;
import com.zbl.zblproject.erp.entity.ErpOrderStatus;
import com.zbl.zblproject.erp.mapper.ErpFinanceLogMapper;
import com.zbl.zblproject.erp.mapper.ErpOrderMapper;
import com.zbl.zblproject.erp.service.ErpOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * @author youlanqiang
 * @version 1.0
 * @date 2018/12/11
 */
@RestController
@Api(tags = "财务审核接口")
@RequestMapping("/finance-log")
public class ErpFinanceLogController {


    private static final Logger logger = LoggerFactory.getLogger(ErpFinanceLogController.class);


    @Value("${img-path}")
    private String imgPath;

    @Autowired
    private ErpFinanceLogMapper erpFinanceLogMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private AdminUserMapper adminUserMapper;

    @Autowired
    private ErpOrderService erpOrderService;

    @Autowired
    private ErpOrderMapper erpOrderMapper;

    @Autowired
    private SupplierMapper supplierMapper;

    @Autowired
    private RechargeLogMapper rechargeLogMapper;

    @GetMapping("/show-certificate/{id}")
    @ApiOperation("显示凭证图片")
    public void showImg(@ApiParam("订单的ID") @PathVariable int id,
                        HttpServletResponse response) {
        ErpFinanceLog log = erpFinanceLogMapper.selectById(id);
        if (log != null && log.getImgPath() != null) {
            File img = new File(log.getImgPath());
            if (img.exists()) {
                String ext = FilenameUtils.getExtension(log.getImgPath());
                response.setContentType("image/jpeg");
                response.addHeader("Content-Disposition",
                        "attachment;fileName=" + log.getOrderNumber() + "." + ext);// 设置文件名
                try (OutputStream stream = response.getOutputStream()) {
                    stream.write(FileUtils.readFileToByteArray(img));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @PostMapping("/submit-certificate/{id}")
    @ApiOperation("提交凭证")
    public Result submitCertificate(@ApiParam("订单的ID") @PathVariable int id,
                                    MultipartFile multipartFile) {
        if (multipartFile == null || multipartFile.isEmpty()) {
            return ResultUtil.error("没有上传任何文件!");
        }
        ErpFinanceLog log = erpFinanceLogMapper.selectById(id);
        if (log == null) {
            return ResultUtil.error("没有这个收付款记录!");
        }
        File imgDir = new File(imgPath);
        if (imgDir.exists()) {
            if (imgDir.isFile()) {
                return ResultUtil.error("保存图片的路径为文件,请通知管理员!");
            }
        } else {
            if (!imgDir.mkdirs()) {
                return ResultUtil.error("创建保存图片文件夹失败,请联系管理员!");
            }
        }
        String ext = FilenameUtils.getExtension(multipartFile.getOriginalFilename());
        if (ext == null) {
            return ResultUtil.error("只支持jpg或png格式的图片!");
        }
        if(!ext.equals("jpg") && !ext.equals("png")){
            return ResultUtil.error("只支持jpg或png格式的图片!");
        }
        String name = UUID.randomUUID() + "." + ext;
        File targetFile = new File(imgDir, name);
        try {
            multipartFile.transferTo(targetFile);
        } catch (IOException e) {
            return ResultUtil.error("保存失败!");
        }
        if (log.getImgPath() != null) {
            FileUtils.deleteQuietly(new File(log.getImgPath()));
        }
        log.setImgPath(targetFile.toPath().toString());
        if (erpFinanceLogMapper.updateById(log) == 1) {
            return ResultUtil.success("上传凭证成功!");
        } else {
            return ResultUtil.error("上传凭证失败!");
        }
    }

    @GetMapping("/page/{current}/{size}")
    @ApiOperation("分页")
    public Result page(@ApiParam("起始时间") @RequestParam("start") String start,
                       @ApiParam("结束时间") @RequestParam("end") String end,
                       @ApiParam("页面") @PathVariable int current,
                       @ApiParam("数量") @PathVariable int size) {
        IPage<ErpFinanceLog> page = new Page<>(current, size);
        QueryWrapper<ErpFinanceLog> wrapper = new QueryWrapper<>();
        if (!StringUtil.isNullOrEmpty(start)) {
            wrapper.ge("checktime", TimeUtil.parseTime(start));
        }
        if (!StringUtil.isNullOrEmpty(end)) {
            wrapper.le("checktime", TimeUtil.parseTime(end));
        }
        wrapper.orderByDesc("id");
        page = erpFinanceLogMapper.selectPage(page, wrapper);
        return ResultUtil.success("成功", page);
    }

    /**
     * 供应商
     */
    @PostMapping("/create-sk/{orderSn}")
    @ApiOperation("创建自定义收款单")
    public Result createSkOrder(@ApiParam("订单号") @PathVariable String orderSn,
                                @ApiParam("应付金额") @RequestParam("total") double total,
                                @ApiParam("返点金额") @RequestParam("rebate") double rebate,
                                @ApiParam("退货金额") @RequestParam("returnMoney") double returnMoney,
                                @ApiParam("欠货金额") @RequestParam("owedMoney") double owedMoney,
                                @ApiParam("抹零金额") @RequestParam("zeroMoney") double zeroMoney,
                                @ApiParam("订单备注") @RequestParam("context") String context,
                                @ApiParam("经销商ID") @RequestParam("userId") int userId,
                                @ApiParam("操作人") @RequestParam("operatorId") int operatorId
    ) {
        AdminUser user = adminUserMapper.selectById(userId);
        if (user == null) {
            return ResultUtil.error("没有对应经销商!");
        }
        ErpFinanceLog log = new ErpFinanceLog();
        log.setStoreName(user.getUserName());
        log.setOrderSn(orderSn);
        log.setOrderNumber("SK" + Instant.now().toEpochMilli());
        log.setContext(context);

        log.setRebateRate(BigDecimal.ZERO);

        log.setReturnMoney(BigDecimal.valueOf(returnMoney));
        log.setOwedMoney(BigDecimal.valueOf(owedMoney));
        log.setZeroMoney(BigDecimal.valueOf(zeroMoney));
        log.setTotal(BigDecimal.valueOf(total));
        log.setRebate(BigDecimal.valueOf(rebate));
        log.setUserBalance(user.getBalance());
        log.setCreater(adminUserMapper.selectNameById(operatorId));
        log.setMode(ErpFinanceLog.MODE_CUSTOMIZE_RECEIPT);
        log.setStatus(ErpOrderStatus.submit.getStatus());
        log.setChecktime(LocalDateTime.now());
        erpFinanceLogMapper.insert(log);
        return ResultUtil.success("自定义收款单创建成功!");
    }

    @PostMapping("/create-fk/{orderSn}")
    @ApiOperation("创建自定义付款单")
    public Result createFkOrder(@ApiParam("订单号") @PathVariable String orderSn,
                                @ApiParam("应付金额") @RequestParam("total") double total,
                                @ApiParam("返点金额") @RequestParam("rebate") double rebate,
                                @ApiParam("退货金额") @RequestParam("returnMoney") double returnMoney,
                                @ApiParam("欠货金额") @RequestParam("owedMoney") double owedMoney,
                                @ApiParam("抹零金额") @RequestParam("zeroMoney") double zeroMoney,
                                @ApiParam("订单备注") @RequestParam("context") String context,
                                @ApiParam("供应商ID") @RequestParam("supplierId") int supplierId,
                                @ApiParam("操作人") @RequestParam("operatorId") int operatorId) {

        Supplier supplier = supplierMapper.selectById(supplierId);
        if (supplier == null) {
            return ResultUtil.error("没有对应供应商!");
        }
        ErpFinanceLog log = new ErpFinanceLog();
        log.setStoreName(supplier.getSuppliersName());
        log.setOrderSn(orderSn);
        log.setOrderNumber("FK" + Instant.now().toEpochMilli());
        log.setContext(context);
        log.setRebateRate(BigDecimal.ZERO);
        log.setReturnMoney(BigDecimal.valueOf(returnMoney));
        log.setOwedMoney(BigDecimal.valueOf(owedMoney));
        log.setZeroMoney(BigDecimal.valueOf(zeroMoney));
        log.setTotal(BigDecimal.valueOf(total));
        log.setCreater(adminUserMapper.selectNameById(operatorId));

        log.setRebate(BigDecimal.valueOf(rebate));

        log.setUserBalance(supplier.getBalance());
        log.setMode(ErpFinanceLog.MODE_CUSTOMIZE_PAYMENT);
        log.setStatus(ErpOrderStatus.submit.getStatus());
        log.setChecktime(LocalDateTime.now());
        erpFinanceLogMapper.insert(log);
        return ResultUtil.success("自定义付款单创建成功!");
    }

    //退货金额, 欠货金额, 返点金额
    @PostMapping("/save-status/{id}")
    @ApiOperation("保存付款状态")
    @Transactional
    public Result saveStatus(@ApiParam("收付款号的ID") @PathVariable int id,
                             @ApiParam("用户ID") @RequestParam("userId") int userId,
                             @ApiParam("退货金额") @RequestParam("returnMoney") double returnMoney,
                             @ApiParam("欠货金额") @RequestParam("owedMoney") double owedMoney,
                             @ApiParam("抹零金额") @RequestParam("zeroMoney") double zeroMoney,
                             @ApiParam("返点") @RequestParam("rebate") double rebate,
                             @ApiParam("已支付") @RequestParam("paid") double paid,
                             @ApiParam("备注") @RequestParam("context") String context) {
        logger.info("pass-status 值 id:{}, 用户ID:{} 退货金额:{} 欠货金额:{} 抹零金额:{} 返点:{} 已支付:{}" +
                "配置:{} ", id, userId, returnMoney, owedMoney, zeroMoney, rebate, paid, context);
        ErpFinanceLog log = erpFinanceLogMapper.selectById(id);
        if (log != null) {
            if (log.getStatus() == ErpOrderStatus.financeFinish.getStatus()) {
                return ResultUtil.error("已完成订单无法修改!");
            }
            log.setUserBalance(adminUserMapper.selectUserBalanceByUserName(log.getStoreName()));
            log.setZeroMoney(BigDecimal.valueOf(zeroMoney));
            log.setRebate(BigDecimal.valueOf(rebate));
            log.setReturnMoney(BigDecimal.valueOf(returnMoney));
            log.setOwedMoney(BigDecimal.valueOf(owedMoney));
            log.setContext(context);
            log.setPaid(BigDecimal.valueOf(paid));
            log.setOperator(adminUserMapper.selectNameById(userId));
            erpFinanceLogMapper.updateById(log);
            return ResultUtil.success("更新成功!");
        }
        return ResultUtil.error("没有查询到对应的订单号");
    }


    //退货金额, 欠货金额, 返点金额
    @PostMapping("/pass-status/{id}")
    @ApiOperation("更新付款的状态")
    @Transactional
    public Result updateStatus(@ApiParam("收付款号的ID") @PathVariable int id,
                               @ApiParam("用户ID") @RequestParam("userId") int userId,
                               @ApiParam("退货金额") @RequestParam("returnMoney") double returnMoney,
                               @ApiParam("欠货金额") @RequestParam("owedMoney") double owedMoney,
                               @ApiParam("抹零金额") @RequestParam("zeroMoney") double zeroMoney,
                               @ApiParam("返点") @RequestParam("rebate") double rebate,
                               @ApiParam("已支付") @RequestParam("paid") double paid,
                               @ApiParam("备注") @RequestParam("context") String context) {
        logger.info("pass-status 值 id:{}, 用户ID:{} 退货金额:{} 欠货金额:{} 抹零金额:{} 返点:{} 已支付:{}" +
                "配置:{} ", id, userId, returnMoney, owedMoney, zeroMoney, rebate, paid, context);
        /**
         * rebate返点，在订单支付时用户扣的款
         * 返点  rebate = total * 经销商返点率
         * 为  total - rebate - returnMoney - owedMoney = 实际付款金额
         *
         */
        ErpFinanceLog log = erpFinanceLogMapper.selectById(id);
        if (log != null) {
            if (log.getStatus() != ErpOrderStatus.submit.getStatus()) {
                return ResultUtil.error("订单状态异常!");
            }
            if (Strings.isNullOrEmpty(log.getImgPath())) {
                return ResultUtil.error("没有上传对应的订单凭证!");
            }
            if (log.getMode() == ErpFinanceLog.MODE_RECEIPT) {
                //收款单更新
                ErpOrder order = erpOrderService.getErpOrder(log.getOrderSn());
                if (order == null) {
                    return ResultUtil.error("没有发现该订单!");
                }
                if (order.getStatus() != ErpOrderStatus.finance.getStatus()) {
                    return ResultUtil.error("订单不是财务审核状态!");
                }
                log.setChecktime(LocalDateTime.now());
                log.setUserBalance(adminUserMapper.selectUserBalanceByUserId(order.getStoreId()));
                log.setTotal(erpOrderMapper.selectOrderTotal(order.getOrderId()));
                log.setStatus(ErpOrderStatus.pass.getStatus());
                log.setStoreName(adminUserMapper.selectNameById(order.getStoreId()));
                log.setMode(ErpFinanceLog.MODE_RECEIPT);
                log.setZeroMoney(BigDecimal.valueOf(zeroMoney));
                log.setRebate(BigDecimal.valueOf(rebate));
                log.setOwedMoney(BigDecimal.valueOf(owedMoney));
                log.setReturnMoney(BigDecimal.valueOf(returnMoney));
                log.setContext(context);
                log.setPaid(BigDecimal.valueOf(paid));
                log.setOperator(adminUserMapper.selectNameById(userId));
                //财务审核完成
                order.setStatus(ErpOrderStatus.financeFinish.getStatus());
                adminUserMapper.deleteUserMoney(order.getStoreId(),
                        log.getRealPrice().subtract(log.getPaid()));
                erpOrderMapper.updateById(order);
                erpFinanceLogMapper.updateById(log);
                return ResultUtil.success("订单更新成功!");

            } else if (log.getMode() == ErpFinanceLog.MODE_PAYMENT) {
                Supplier supplier = supplierMapper.selectSupplierByName(log.getStoreName());
                if (supplier == null) {
                    return ResultUtil.error("没有发现供应商");
                }
                log.setUserBalance(supplier.getBalance());
                log.setReturnMoney(BigDecimal.valueOf(returnMoney));
                log.setOwedMoney(BigDecimal.valueOf(owedMoney));
                log.setRebate(BigDecimal.valueOf(rebate));
                log.setZeroMoney(BigDecimal.valueOf(zeroMoney));
                log.setContext(context);
                log.setPaid(BigDecimal.valueOf(paid));
                log.setOperator(adminUserMapper.selectNameById(userId));
                //经销商扣款
                log.setStatus(ErpOrderStatus.pass.getStatus());
                if (erpFinanceLogMapper.updateById(log) == 1) {
                    supplierMapper.addSuplierBalance(supplier.getSuppliersId(),
                            log.getRealPrice().subtract(log.getPaid()));
                    return ResultUtil.success("更新成功!");
                } else {
                    return ResultUtil.error("更新失败!");
                }
            } else if (log.getMode() == ErpFinanceLog.MODE_CUSTOMIZE_PAYMENT) {
                Supplier supplier = supplierMapper.selectSupplierByName(log.getStoreName());
                if (supplier == null) {
                    return ResultUtil.error("没有对应供应商!");
                }
                log.setUserBalance(supplier.getBalance());
                log.setZeroMoney(BigDecimal.valueOf(zeroMoney));
                log.setRebate(BigDecimal.valueOf(rebate));
                log.setReturnMoney(BigDecimal.valueOf(returnMoney));
                log.setOwedMoney(BigDecimal.valueOf(owedMoney));
                log.setContext(context);
                log.setPaid(BigDecimal.valueOf(paid));
                log.setOperator(adminUserMapper.selectNameById(userId));

                log.setStatus(ErpOrderStatus.pass.getStatus());
                if (erpFinanceLogMapper.updateById(log) == 1) {
                    boolean result = supplierMapper.addSuplierBalance(supplier.getSuppliersId(),
                            log.getRealPrice().subtract(log.getPaid()));
                    if (result) {
                        return ResultUtil.success("更新成功!");
                    } else {
                        return ResultUtil.error("更新失败!");
                    }
                }
                return ResultUtil.error("更新失败!");
            } else if (log.getMode() == ErpFinanceLog.MODE_CUSTOMIZE_RECEIPT) {

                log.setUserBalance(adminUserMapper.selectUserBalanceByUserName(log.getStoreName()));
                log.setZeroMoney(BigDecimal.valueOf(zeroMoney));
                log.setRebate(BigDecimal.valueOf(rebate));
                log.setReturnMoney(BigDecimal.valueOf(returnMoney));
                log.setOwedMoney(BigDecimal.valueOf(owedMoney));
                log.setContext(context);
                log.setPaid(BigDecimal.valueOf(paid));
                log.setOperator(adminUserMapper.selectNameById(userId));
                log.setStatus(ErpOrderStatus.pass.getStatus());
                if (erpFinanceLogMapper.updateById(log) == 1) {
                    boolean result = adminUserMapper.deleteUserMoneyByName(log.getStoreName(),
                            log.getRealPrice().subtract(log.getPaid()));
                    if (result) {
                        return ResultUtil.success("更新成功!");
                    } else {
                        return ResultUtil.error("更新失败!");
                    }
                }
                return ResultUtil.error("更新失败!");
            } else {
                return ResultUtil.error("订单状态无法更新!");
            }
        }
        return ResultUtil.error("没有查询到对应的订单号");
    }


    @PostMapping("/roll-status/{id}")
    @ApiOperation("退回付款的状态")
    public Result rollStatus(@ApiParam("收付款号的ID") @PathVariable int id) {
        ErpFinanceLog log = erpFinanceLogMapper.selectById(id);
        if (log != null) {
            if (log.getStatus() != ErpOrderStatus.submit.getStatus()) {
                return ResultUtil.error("订单状态异常!");
            }
            if (log.getMode() == ErpFinanceLog.MODE_RECEIPT) {
                // return ResultUtil.error("不支持更新收款单!");
                if (erpOrderService.rollbackOrder(log.getOrderSn())) {
                    return ResultUtil.success("退回成功");
                } else {
                    return ResultUtil.error("退回失败!");
                }
            } else if (log.getMode() == ErpFinanceLog.MODE_PAYMENT) {
                log.setStatus(ErpOrderStatus.returnOrder.getStatus());
                if (erpFinanceLogMapper.updateById(log) == 1) {
                    orderMapper.updateOrderConfirm(log.getOrderSn(), 0);
                    return ResultUtil.success("退回成功");
                } else {
                    return ResultUtil.error("退回失败!");
                }
            }
        }
        return ResultUtil.error("没有查询到对应的订单号");
    }


    @GetMapping("/recharge-log/{current}/{size}")
    @ApiOperation("所有的充值记录")
    public Result rechargeLogOfAll(@ApiParam("页数") @PathVariable int current,
                                   @ApiParam("数量") @PathVariable int size,
                                   @ApiParam("开始时间") @RequestParam String start,
                                   @ApiParam("结束时间") @RequestParam String end) {

        QueryWrapper<RechargeLog> wrapper = new QueryWrapper<>();
        if (!StringUtil.isNullOrEmpty(start)) {
            wrapper.ge("time", TimeUtil.parseTime(start));
        }
        if (!StringUtil.isNullOrEmpty(end)) {
            wrapper.le("time", TimeUtil.parseTime(end));
        }
        wrapper.orderByDesc("id");
        IPage<RechargeLog> page = new Page<>(current, size);
        page = rechargeLogMapper.selectPage(page, wrapper);
        page.getRecords().forEach(x -> {
            if (x.getMode() == 0) {
                x.setAdminUser(adminUserMapper.selectById(x.getUserId()));
            } else if (x.getMode() == 1) {
                x.setSupplier(supplierMapper.selectById(x.getUserId()));
            }
        });

        return ResultUtil.success("成功", page);
    }

}
